﻿/**************************************************************************\
    Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/

namespace C4F.DevKit.Contacts
{
    using System;
    using System.Collections.Generic;
    using C4F.DevKit.Contacts.Standard;
    using C4F.DevKit.Contacts.Interop;

    public class GroupView : ContactView
    {
        private ILabeledPropertyCollection<Person> _members;

        public GroupView(Contact contact)
            : base(contact)
        { }

        private void _Validate()
        {
            Source.VerifyAccess();
        }

        // These committer/creator functions are a bit indirect, but I don't think it should matter.

        private void _CommitPerson(Contact contact, string arrayNode, Person value)
        {
            Assert.IsTrue(arrayNode.StartsWith(PropertyNames.PersonCollection + PropertyNames.PersonArrayNode));
            int index = ContactUtil.GetIndexFromNode(arrayNode);
            contact.People[index] = value;
        }

        private Person _CreatePerson(Contact contact, string arrayNode)
        {
            Assert.IsTrue(arrayNode.StartsWith(PropertyNames.PersonCollection + PropertyNames.PersonArrayNode));
            int index = ContactUtil.GetIndexFromNode(arrayNode);
            return contact.People[index];
        }

        public ILabeledPropertyCollection<Person> Members
        {
            get
            {
                _Validate();
                if (null == _members)
                {
                    _members = new SchematizedLabeledPropertyCollection2<Person>(Source, PropertyNames.PersonCollection, PropertyNames.PersonArrayNode, PersonLabels.Member, _CreatePerson, _CommitPerson);
                }
                return _members;
            }
        }

        /// <summary>
        /// Expand the members of this group to gather the e-mail addresses.
        /// </summary>
        public ICollection<string> ExpandEmailAddresses()
        {
            List<string> retList = new List<string>();
            // As we recurse through the members, keep track of the ContactIds
            //    to avoid recursively looping.
            List<string> idList = new List<string>();

            _ExpandEmailAddresses(this, idList, retList);

            return retList;
        }

        private void _ExpandEmailAddresses(GroupView group, List<string> idList, List<string> retList)
        {
            foreach (Person person in this.Members)
            {
                if (null != person.Contact && ContactType.Group == person.Contact.ContactType)
                {
                    if (!idList.Contains(person.Contact.Id))
                    {
                        idList.Add(person.Contact.Id);
                        _ExpandEmailAddresses(new GroupView(person.Contact), idList, retList);
                    }
                }

                // Pick up the e-mail address for this member, even if it's also a group.
                if (null != person.Email)
                {
                    retList.Add(person.Email);
                }
            }
        }
    }
}
